-
Notifications
You must be signed in to change notification settings - Fork 15.1k
[libc++] implement adjacent_view #165089
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
huixie90
wants to merge
5
commits into
llvm:main
Choose a base branch
from
huixie90:hxie/adjacent_view
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
[libc++] implement adjacent_view #165089
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
|
@llvm/pr-subscribers-libcxx Author: Hui (huixie90) ChangesPatch is 147.28 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/165089.diff 41 Files Affected:
diff --git a/libcxx/docs/ReleaseNotes/22.rst b/libcxx/docs/ReleaseNotes/22.rst
index ec23ba9d1e3a1..b3186f7e486d7 100644
--- a/libcxx/docs/ReleaseNotes/22.rst
+++ b/libcxx/docs/ReleaseNotes/22.rst
@@ -39,7 +39,7 @@ Implemented Papers
------------------
- P2321R2: ``zip`` (`Github <https://llvm.org/PR105169>`__) (The paper is partially implemented. ``zip_transform_view``
- is implemented in this release)
+ and `adjacent_view` are implemented in this release)
- P3044R2: sub-``string_view`` from ``string`` (`Github <https://llvm.org/PR148140>`__)
- P3223R2: Making ``std::istream::ignore`` less surprising (`Github <https://llvm.org/PR148178>`__)
- P3060R3: Add ``std::views::indices(n)`` (`Github <https://llvm.org/PR148175>`__)
diff --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt
index ddace8bf8c728..9d725f49a18f1 100644
--- a/libcxx/include/CMakeLists.txt
+++ b/libcxx/include/CMakeLists.txt
@@ -696,6 +696,7 @@ set(files
__random/uniform_real_distribution.h
__random/weibull_distribution.h
__ranges/access.h
+ __ranges/adjacent_view.h
__ranges/all.h
__ranges/as_rvalue_view.h
__ranges/chunk_by_view.h
@@ -739,6 +740,7 @@ set(files
__ranges/view_interface.h
__ranges/views.h
__ranges/zip_transform_view.h
+ __ranges/zip_utils.h
__ranges/zip_view.h
__split_buffer
__std_mbstate_t.h
diff --git a/libcxx/include/__ranges/adjacent_view.h b/libcxx/include/__ranges/adjacent_view.h
new file mode 100644
index 0000000000000..cdb62385a5795
--- /dev/null
+++ b/libcxx/include/__ranges/adjacent_view.h
@@ -0,0 +1,408 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___RANGES_ADJACENT_VIEW_H
+#define _LIBCPP___RANGES_ADJACENT_VIEW_H
+
+#include <__config>
+
+#include <__algorithm/min.h>
+#include <__compare/three_way_comparable.h>
+#include <__concepts/constructible.h>
+#include <__concepts/convertible_to.h>
+#include <__concepts/equality_comparable.h>
+#include <__cstddef/size_t.h>
+#include <__functional/invoke.h>
+#include <__functional/operations.h>
+#include <__iterator/concepts.h>
+#include <__iterator/incrementable_traits.h>
+#include <__iterator/iter_move.h>
+#include <__iterator/iter_swap.h>
+#include <__iterator/iterator_traits.h>
+#include <__iterator/next.h>
+#include <__iterator/prev.h>
+#include <__ranges/access.h>
+#include <__ranges/all.h>
+#include <__ranges/concepts.h>
+#include <__ranges/empty_view.h>
+#include <__ranges/enable_borrowed_range.h>
+#include <__ranges/range_adaptor.h>
+#include <__ranges/size.h>
+#include <__ranges/view_interface.h>
+#include <__ranges/zip_utils.h>
+#include <__type_traits/common_type.h>
+#include <__type_traits/is_nothrow_constructible.h>
+#include <__type_traits/make_unsigned.h>
+#include <__type_traits/maybe_const.h>
+#include <__utility/declval.h>
+#include <__utility/forward.h>
+#include <__utility/integer_sequence.h>
+#include <__utility/move.h>
+#include <array>
+#include <tuple>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if _LIBCPP_STD_VER >= 23
+
+namespace ranges {
+
+template <forward_range _View, size_t _Np>
+ requires view<_View> && (_Np > 0)
+class adjacent_view : public view_interface<adjacent_view<_View, _Np>> {
+private:
+ _LIBCPP_NO_UNIQUE_ADDRESS _View __base_ = _View();
+
+ template <bool>
+ class __iterator;
+
+ template <bool>
+ class __sentinel;
+
+ struct __as_sentinel {};
+
+public:
+ _LIBCPP_HIDE_FROM_ABI adjacent_view()
+ requires default_initializable<_View>
+ = default;
+
+ _LIBCPP_HIDE_FROM_ABI constexpr explicit adjacent_view(_View __base) : __base_(std::move(__base)) {}
+
+ _LIBCPP_HIDE_FROM_ABI constexpr _View base() const&
+ requires copy_constructible<_View>
+ {
+ return __base_;
+ }
+ _LIBCPP_HIDE_FROM_ABI constexpr _View base() && { return std::move(__base_); }
+
+ _LIBCPP_HIDE_FROM_ABI constexpr auto begin()
+ requires(!__simple_view<_View>)
+ {
+ return __iterator<false>(ranges::begin(__base_), ranges::end(__base_));
+ }
+
+ _LIBCPP_HIDE_FROM_ABI constexpr auto begin() const
+ requires range<const _View> // todo: this seems under-constrained. lwg issue?
+ {
+ return __iterator<true>(ranges::begin(__base_), ranges::end(__base_));
+ }
+
+ _LIBCPP_HIDE_FROM_ABI constexpr auto end()
+ requires(!__simple_view<_View>)
+ {
+ if constexpr (common_range<_View>) {
+ return __iterator<false>(__as_sentinel{}, ranges::begin(__base_), ranges::end(__base_));
+ } else {
+ return __sentinel<false>(ranges::end(__base_));
+ }
+ }
+
+ _LIBCPP_HIDE_FROM_ABI constexpr auto end() const
+ requires range<const _View>
+ {
+ if constexpr (common_range<const _View>) {
+ return __iterator<true>(__as_sentinel{}, ranges::begin(__base_), ranges::end(__base_));
+ } else {
+ return __sentinel<true>(ranges::end(__base_));
+ }
+ }
+
+ _LIBCPP_HIDE_FROM_ABI constexpr auto size()
+ requires sized_range<_View>
+ {
+ using _ST = decltype(ranges::size(__base_));
+ using _CT = common_type_t<_ST, size_t>;
+ auto __sz = static_cast<_CT>(ranges::size(__base_));
+ __sz -= std::min<_CT>(__sz, _Np - 1);
+ return static_cast<_ST>(__sz);
+ }
+
+ _LIBCPP_HIDE_FROM_ABI constexpr auto size() const
+ requires sized_range<const _View>
+ {
+ using _ST = decltype(ranges::size(__base_));
+ using _CT = common_type_t<_ST, size_t>;
+ auto __sz = static_cast<_CT>(ranges::size(__base_));
+ __sz -= std::min<_CT>(__sz, _Np - 1);
+ return static_cast<_ST>(__sz);
+ }
+};
+
+template <forward_range _View, size_t _Np>
+ requires view<_View> && (_Np > 0)
+template <bool _Const>
+class adjacent_view<_View, _Np>::__iterator {
+ friend adjacent_view;
+ using _Base = __maybe_const<_Const, _View>;
+ array<iterator_t<_Base>, _Np> __current_ = array<iterator_t<_Base>, _Np>();
+
+ _LIBCPP_HIDE_FROM_ABI constexpr __iterator(iterator_t<_Base> __first, sentinel_t<_Base> __last) {
+ __current_[0] = __first;
+ for (int __i = 1; __i < static_cast<int>(_Np); ++__i) {
+ __current_[__i] = ranges::next(__current_[__i - 1], 1, __last);
+ }
+ }
+
+ _LIBCPP_HIDE_FROM_ABI constexpr __iterator(__as_sentinel, iterator_t<_Base> __first, iterator_t<_Base> __last) {
+ if constexpr (!bidirectional_range<_Base>) {
+ __current_.fill(__last);
+ } else {
+ __current_[_Np - 1] = __last;
+ for (int __i = static_cast<int>(_Np) - 2; __i >= 0; --__i) {
+ __current_[__i] = ranges::prev(__current_[__i + 1], 1, __first);
+ }
+ }
+ }
+
+ template <class _Iter, size_t... _Is>
+ _LIBCPP_HIDE_FROM_ABI explicit constexpr __iterator(_Iter&& __i, index_sequence<_Is...>)
+ : __current_{std::move(__i.__current_[_Is])...} {}
+
+ static consteval auto __get_iterator_concept() {
+ if constexpr (random_access_range<_Base>)
+ return random_access_iterator_tag{};
+ else if constexpr (bidirectional_range<_Base>)
+ return bidirectional_iterator_tag{};
+ else
+ return forward_iterator_tag{};
+ }
+
+ template <class _Tp, size_t... _Is>
+ static auto __repeat_tuple_helper(index_sequence<_Is...>) -> tuple<decltype((_Is, std::declval<_Tp (*)()>()()))...>;
+
+public:
+ using iterator_category = input_iterator_tag;
+ using iterator_concept = decltype(__get_iterator_concept());
+ using value_type = decltype(__repeat_tuple_helper<range_value_t<_Base>>(make_index_sequence<_Np>{}));
+ using difference_type = range_difference_t<_Base>;
+
+ _LIBCPP_HIDE_FROM_ABI __iterator() = default;
+ _LIBCPP_HIDE_FROM_ABI constexpr __iterator(__iterator<!_Const> __i)
+ requires _Const && convertible_to<iterator_t<_View>, iterator_t<_Base>>
+ : __iterator(std::move(__i), make_index_sequence<_Np>{}) {}
+
+ _LIBCPP_HIDE_FROM_ABI constexpr auto operator*() const {
+ return ranges::__tuple_transform([](auto& __i) -> decltype(auto) { return *__i; }, __current_);
+ }
+
+ _LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator++() {
+ for (auto& __i : __current_) {
+ ++__i;
+ }
+ return *this;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI constexpr __iterator operator++(int) {
+ auto __tmp = *this;
+ ++*this;
+ return __tmp;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator--()
+ requires bidirectional_range<_Base>
+ {
+ for (auto& __i : __current_) {
+ --__i;
+ }
+ return *this;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI constexpr __iterator operator--(int)
+ requires bidirectional_range<_Base>
+ {
+ auto __tmp = *this;
+ --*this;
+ return __tmp;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator+=(difference_type __x)
+ requires random_access_range<_Base>
+ {
+ for (auto& __i : __current_) {
+ __i += __x;
+ }
+ return *this;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator-=(difference_type __x)
+ requires random_access_range<_Base>
+ {
+ for (auto& __i : __current_) {
+ __i -= __x;
+ }
+ return *this;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI constexpr auto operator[](difference_type n) const
+ requires random_access_range<_Base>
+ {
+ return ranges::__tuple_transform([&](auto& __i) -> decltype(auto) { return __i[n]; }, __current_);
+ }
+
+ _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const __iterator& __x, const __iterator& __y) {
+ return __x.__current_.back() == __y.__current_.back();
+ }
+
+ _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator<(const __iterator& __x, const __iterator& __y)
+ requires random_access_range<_Base>
+ {
+ return __x.__current_.back() < __y.__current_.back();
+ }
+
+ _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator>(const __iterator& __x, const __iterator& __y)
+ requires random_access_range<_Base>
+ {
+ return __y < __x;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator<=(const __iterator& __x, const __iterator& __y)
+ requires random_access_range<_Base>
+ {
+ return !(__y < __x);
+ }
+
+ _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator>=(const __iterator& __x, const __iterator& __y)
+ requires random_access_range<_Base>
+ {
+ return !(__x < __y);
+ }
+
+ _LIBCPP_HIDE_FROM_ABI friend constexpr auto operator<=>(const __iterator& __x, const __iterator& __y)
+ requires random_access_range<_Base> && three_way_comparable<iterator_t<_Base>>
+ {
+ return __x.__current_.back() <=> __y.__current_.back();
+ }
+
+ _LIBCPP_HIDE_FROM_ABI friend constexpr __iterator operator+(const __iterator& __i, difference_type __n)
+ requires random_access_range<_Base>
+ {
+ auto __r = __i;
+ __r += __n;
+ return __r;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI friend constexpr __iterator operator+(difference_type __n, const __iterator& __i)
+ requires random_access_range<_Base>
+ {
+ return __i + __n;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI friend constexpr __iterator operator-(const __iterator& __i, difference_type __n)
+ requires random_access_range<_Base>
+ {
+ auto __r = __i;
+ __r -= __n;
+ return __r;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI friend constexpr difference_type operator-(const __iterator& __x, const __iterator& __y)
+ requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
+ {
+ return __x.__current_.back() - __y.__current_.back();
+ }
+
+ _LIBCPP_HIDE_FROM_ABI friend constexpr auto iter_move(const __iterator& __i) noexcept(
+ noexcept(ranges::iter_move(std::declval<const iterator_t<_Base>&>())) &&
+ is_nothrow_move_constructible_v<range_rvalue_reference_t<_Base>>) {
+ return ranges::__tuple_transform(ranges::iter_move, __i.__current_);
+ }
+
+ _LIBCPP_HIDE_FROM_ABI friend constexpr void iter_swap(const __iterator& __l, const __iterator& __r) noexcept(
+ noexcept(ranges::iter_swap(std::declval<iterator_t<_Base>>(), std::declval<iterator_t<_Base>>())))
+ requires indirectly_swappable<iterator_t<_Base>>
+ {
+ for (size_t __i = 0; __i < _Np; ++__i) {
+ ranges::iter_swap(__l.__current_[__i], __r.__current_[__i]);
+ }
+ }
+};
+
+template <forward_range _View, size_t _Np>
+ requires view<_View> && (_Np > 0)
+template <bool _Const>
+class adjacent_view<_View, _Np>::__sentinel {
+ friend adjacent_view;
+ using _Base = __maybe_const<_Const, _View>;
+ sentinel_t<_Base> __end_ = sentinel_t<_Base>();
+
+ _LIBCPP_HIDE_FROM_ABI constexpr explicit __sentinel(sentinel_t<_Base> __end) { __end_ = std::move(__end); }
+
+public:
+ _LIBCPP_HIDE_FROM_ABI __sentinel() = default;
+
+ _LIBCPP_HIDE_FROM_ABI constexpr __sentinel(__sentinel<!_Const> __i)
+ requires _Const && convertible_to<sentinel_t<_View>, sentinel_t<_Base>>
+ : __end_(std::move(__i.__end_)) {}
+
+ template <bool _OtherConst>
+ requires sentinel_for<sentinel_t<_Base>, iterator_t<__maybe_const<_OtherConst, _View>>>
+ _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const __iterator<_OtherConst>& __x, const __sentinel& __y) {
+ return __x.__current_.back() == __y.__end_;
+ }
+
+ template <bool _OtherConst>
+ requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<__maybe_const<_OtherConst, _View>>>
+ _LIBCPP_HIDE_FROM_ABI friend constexpr range_difference_t<__maybe_const<_OtherConst, _View>>
+ operator-(const __iterator<_OtherConst>& __x, const __sentinel& __y) {
+ return __x.__current_.back() - __y.__end_;
+ }
+
+ template <bool _OtherConst>
+ requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<__maybe_const<_OtherConst, _View>>>
+ _LIBCPP_HIDE_FROM_ABI friend constexpr range_difference_t<__maybe_const<_OtherConst, _View>>
+ operator-(const __sentinel& __y, const __iterator<_OtherConst>& __x) {
+ return __y.__end_ - __x.__current_.back();
+ }
+};
+
+template <class _View, size_t _Np>
+constexpr bool enable_borrowed_range<adjacent_view<_View, _Np>> = enable_borrowed_range<_View>;
+
+namespace views {
+namespace __adjacent {
+
+template <size_t _Np>
+struct __fn : __range_adaptor_closure<__fn<_Np>> {
+ template <class _Range>
+ requires(_Np == 0 && forward_range<_Range &&>)
+ _LIBCPP_HIDE_FROM_ABI static constexpr auto operator()(_Range&&) noexcept {
+ return empty_view<tuple<>>{};
+ }
+
+ template <class _Ranges>
+ _LIBCPP_HIDE_FROM_ABI static constexpr auto operator()(_Ranges&& __range) noexcept(
+ noexcept(adjacent_view<views::all_t<_Ranges&&>, _Np>(std::forward<_Ranges>(__range))))
+ -> decltype(adjacent_view<views::all_t<_Ranges&&>, _Np>(std::forward<_Ranges>(__range))) {
+ return adjacent_view<views::all_t<_Ranges&&>, _Np>(std::forward<_Ranges>(__range));
+ }
+};
+
+} // namespace __adjacent
+inline namespace __cpo {
+template <size_t _Np>
+inline constexpr auto adjacent = __adjacent::__fn<_Np>{};
+inline constexpr auto pairwise = adjacent<2>;
+} // namespace __cpo
+} // namespace views
+} // namespace ranges
+
+#endif // _LIBCPP_STD_VER >= 23
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___RANGES_ADJACENT_VIEW_H
\ No newline at end of file
diff --git a/libcxx/include/__ranges/zip_utils.h b/libcxx/include/__ranges/zip_utils.h
new file mode 100644
index 0000000000000..d993e2c05b0d6
--- /dev/null
+++ b/libcxx/include/__ranges/zip_utils.h
@@ -0,0 +1,49 @@
+
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___RANGES_ZIP_VIEW_H
+#define _LIBCPP___RANGES_ZIP_VIEW_H
+
+#include <__config>
+
+#include <__functional/invoke.h>
+#include <__utility/forward.h>
+#include <tuple>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if _LIBCPP_STD_VER >= 23
+
+namespace ranges {
+
+template <class _Fun, class _Tuple>
+_LIBCPP_HIDE_FROM_ABI constexpr auto __tuple_transform(_Fun&& __f, _Tuple&& __tuple) {
+ return std::apply(
+ [&]<class... _Types>(_Types&&... __elements) {
+ return tuple<invoke_result_t<_Fun&, _Types>...>(std::invoke(__f, std::forward<_Types>(__elements))...);
+ },
+ std::forward<_Tuple>(__tuple));
+}
+
+} // namespace ranges
+#endif // _LIBCPP_STD_VER >= 23
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___RANGES_ZIP_VIEW_H
\ No newline at end of file
diff --git a/libcxx/include/__ranges/zip_view.h b/libcxx/include/__ranges/zip_view.h
index ce00c98710c4e..bd54f37028e45 100644
--- a/libcxx/include/__ranges/zip_view.h
+++ b/libcxx/include/__ranges/zip_view.h
@@ -7,8 +7,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef _LIBCPP___RANGES_ZIP_VIEW_H
-#define _LIBCPP___RANGES_ZIP_VIEW_H
+#ifndef _LIBCPP___RANGES_ZIP_UTILS_H
+#define _LIBCPP___RANGES_ZIP_UTILS_H
#include <__config>
@@ -31,6 +31,7 @@
#include <__ranges/enable_borrowed_range.h>
#include <__ranges/size.h>
#include <__ranges/view_interface.h>
+#include <__ranges/zip_utils.h>
#include <__type_traits/is_nothrow_constructible.h>
#include <__type_traits/make_unsigned.h>
#include <__utility/declval.h>
@@ -58,15 +59,6 @@ concept __zip_is_common =
(!(bidirectional_range<_Ranges> && ...) && (common_range<_Ranges> && ...)) ||
((random_access_range<_Ranges> && ...) && (sized_range<_Ranges> && ...));
-template <class _Fun, class _Tuple>
-_LIBCPP_HIDE_FROM_ABI constexpr auto __tuple_transform(_Fun&& __f, _Tuple&& __tuple) {
- return std::apply(
- [&]<class... _Types>(_Types&&... __elements) {
- return tuple<invoke_result_t<_Fun&, _Types>...>(std::invoke(__f, std::forward<_Types>(__elements))...);
- },
- std::forward<_Tuple>(__tuple));
-}
-
template <class _Fun, class _Tuple>
_LIBCPP_HIDE_FROM_ABI constexpr void __tuple_for_each(_Fun&& __f, _Tuple&& __tuple) {
std::apply(
@@ -504,4 +496,4 @@ _LIBCPP_END_NAMESPACE_STD
_LIBCPP_POP_MACROS
-#endif // _LIBCPP___RANGES_ZIP_VIEW_H
+#endif // _LIBCPP___RANGES_ZIP_UTILS_H
diff --git a/libcxx/include/module.modulemap.in b/libcxx/include/module.modulemap.in
index 894093b409e11..e2b60cf8607db 100644
--- a/libcxx/include/module.modulemap.in
+++ b/libcxx/include/module.modulemap.in
@@ -1850,6 +1850,7 @@ module std [system] {
module ranges {
module access { header "__ranges/access.h" }
+ module adjacent_view { header "__ranges/adjacent_view.h" }
module all {
header "__ranges/all.h"
export std.ranges.ref_view
@@ -1947,6 +1948,9 @@ module std [system] {
header "__ranges/zip_view.h"
export std.utility.pair
}
+ module zip_utils {
+ header "__ranges/zip_utils.h"
+ }
module zip_transform_view {
header "__ranges/zip_transform_view.h"
}
diff --git a/libcxx/include/ranges b/libcxx/include/ranges
index cfaa66a0831b3..fe272579ca898 100644
--- a/libcxx/include/ranges
+++ b/libcxx/include/ranges
@@ -353,6 +353,20 @@ namespace std::ranges {
namespace views { inline constexpr unspecified zip_transform = unspecified; } // C++23
+ // [range.adjacent], adjacent view
+ template<forward_range V, size_t N>
+ requires view<V> && (N > 0)
+ class adjacent_view;
+
+ template<class V, size_t N>
+ constexpr bool enable_borrowed_range<adjacent_view<V, N>> =
+ enable_borrowed_range<V>;
+
+ namespace views {
+ template<size_t N>
+ constexpr unspecified adjacent = unspecified;
+ inline constexpr auto pairwise = adjacent<2>;
+ }
// [range.as.rvalue]
template <view V>
@@ -411,6 +425,7 @@ namespace std {
# if _LIBCPP_STD_VER >= 20
# include <__ranges/access.h>
+# include <__ranges/adjacent_view.h>
# include <__ranges/all.h>
# include <__ranges/common_view.h>
# include <__ranges/concepts.h>
diff --git a/libcxx/modules/std/ranges.inc b/libcxx...
[truncated]
|
|
✅ With the latest revision this PR passed the C/C++ code formatter. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
No description provided.